const { Role, utils, Team } = require('board-game');
const extend = require('extend');

const {game: gameConfig} = require('./config');

class MazeRole extends Role {
    constructor(server, room, player, team, index) {
        super(server, room, player, team, index);
        this.location = false;
        this.shown = false;
        this.start();
    }

    start() {
        this.direction = false;
        this.face = Object.keys(gameConfig.directions)[Math.floor(Math.random() * 4)];
        this.overTick = 0;
        this.nexts = [];
    }

    moveStart(direction) {
        const index = this.nexts.indexOf(direction);
        this.nexts.push(direction);
        if (index !== -1) {
            this.nexts.splice(index, 1);
        }
    }
    moveEnd(direction) {
        const index = this.nexts.indexOf(direction);
        if (index !== -1) {
            this.nexts.splice(index, 1);
        }
    }

    step(board) {
        if (!this.direction) {
            this.direction = this.nexts.length ? this.nexts[this.nexts.length - 1] : false;
        }
        if (this.direction) {
            this.face = this.direction;
            const direction = gameConfig.directions[this.direction];
            const next = { x: this.location.x + direction.x, y: this.location.y + direction.y };
            if (this.overTick !== 0 || board.map[next.y][next.x] !== 1) {
                this.location.dx += direction.x;
                this.location.dy += direction.y;
                if (Math.abs(this.location.dx) === gameConfig.tick.step || Math.abs(this.location.dy) === gameConfig.tick.step) {
                    const prev = this.direction;
                    this.location.dx = this.location.dy = 0;
                    this.location.x = next.x;
                    this.location.y = next.y;
                    this.direction = this.nexts.length ? this.nexts[this.nexts.length - 1] : false;
                    if (this.overTick === 0) {
                        return prev;
                    }
                }
            } else {
                this.direction = this.nexts.length ? this.nexts[this.nexts.length - 1] : false;
            }
        }
        return false;
    }

    toOver(board) {
        if (this.overTick === 0) {
            this.overTick = board.tick;
            const size = board.map.length;
            const halfRenderSize = gameConfig.render.size / 2;
            if (this.location.x > size - halfRenderSize) {
                this.location.x = size - halfRenderSize;
            } else if (this.location.x < halfRenderSize - 1) {
                this.location.x = halfRenderSize - 1;
            }
            if (this.location.y > size - halfRenderSize) {
                this.location.y = size - halfRenderSize;
            } else if (this.location.y < halfRenderSize - 1) {
                this.location.y = halfRenderSize - 1;
            }
        }
    }
    isOver() {
        return this.overTick > 0;
    }
    over() {
        const result = super.over();
        result.title = 'Game over';
        result.scores = [...this.room.roles].sort((a, b) => a.overTick - b.overTick).map(role => ({ role: role.player.name, group: role.group + 1, overTime: gameConfig.asTime(role.overTick) }))
        return result;
    }

    get data() {
        return extend(super.data, {
            direction: this.direction,
            face: this.face,
            location: { ...this.location },
            overTick: this.overTick,
            shown: this.shown ? utils.asObject(this.shown, true) : false
        })
    }
    
}

module.exports = MazeRole;